package com.pine.app.module.security.core.common.enums;

import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author xiaoyuan
 * @create 2019/9/30
 **/
public enum ErrorType {

    ILLEGAL_CODE(1001, "错误的授权码"), //错误的授权码
    ILLEGAL_ACCESS_TOKEN(1002, "错误的access_token"), //错误的access_token
    ILLEGAL_CLIENT_ID(1003, "不合法的客户端信息"),//不合法的客户端信息
    ILLEGAL_CLIENT_SECRET(1004, "客户端密钥错误"),//客户端密钥错误
    ILLEGAL_GRANT_TYPE(1005, "错误的授权方式"), //错误的授权方式
    ILLEGAL_RESPONSE_TYPE(1006, "response_type错误"),//response_type 错误
    ILLEGAL_AUTHORIZATION(1007, "Authorization错误"),//Authorization错误
    ILLEGAL_REFRESH_TOKEN(1008, "refresh_token错误"),//refresh_token 错误
    ILLEGAL_REDIRECT_URI(1009, "redirect_url 错误"), //redirect_url错误
    ILLEGAL_SCOPE(1010, "scope错误"), //scope 错误
    ILLEGAL_USERNAME_OR_PASSWORD(1011, "用户名或者密码错误"), //用户名或者密码错误
    ACCOUNT_DISABLED(1012, "账户已禁用"), //用户名或者密码错误
    ACCOUNT_NONLOCKED(1013, "账户已被锁"), //用户名或者密码错误
    ACCOUNT_NONEXPIRED(1014, "账户已过期"), //用户名或者密码错误


    SCOPE_OUT_OF_RANGE(2010, "scope超出范围"), //scope超出范围
    TOKEN_NOT_NULL(4009, "token不能为空"), //token不能为空
    UNAUTHORIZED_CLIENT(4010, "无权限访问"), //无权限访问
    EXPIRED_TOKEN(4011, "token已过期"), //TOKEN过期
    INVALID_TOKEN(4012, "token已失效"), //TOKEN已失效
    UNSUPPORTED_GRANT_TYPE(4013, "不支持的认证类型"), //不支持的认证类型
    UNSUPPORTED_RESPONSE_TYPE(4014, "不支持的ResponseType"), //不支持的响应类型

    EXPIRED_CODE(4015, "code已过期"), //AUTHORIZATION_CODE过期
    EXPIRED_REFRESH_TOKEN(4020, "refresh_token已过期"), //REFRESH_TOKEN过期

    CLIENT_DISABLED(4016, "客户端已被禁用"),//客户端已被禁用

    CLIENT_NOT_EXIST(4040, "客户端不存在"),//客户端不存在
    CLIENT_NOT_NULL(4041, "client_id不能为空"),//客户端不能为空
    CLIENT_SECRET_NOT_NULL(4042, "客户端密钥能为空"),//客户端密钥能为空

    USER_NOT_EXIST(4043, "用户不存在"),//客户端不存在

    STATE_ERROR(4044, "stat错误"), //stat错误
    SCOPE_NOT_NULL(4045, "scope不能为空"),//SCOPE不能为空

    CODE_NOT_NULL(4046, "code不能为空"),//code不能为空
    REDIRECT_URI_NOT_NULL(4047, "redirect_uri不能为空"),//跳转连接不能为空
    REFRESH_TOKEN_NOT_NULL(4048, "response_type不能为空"),//response_type不能为空

    RESPONSE_TYPE_NOT_NULL(4049, "refresh_token不能为空"),//refresh_token不能为空
    AUTHENTICATION_ERROR(401, "认证失败"), //此资源需要身份认证

    ACCESS_DENIED(403, "无权限访问"), //此资源需要身份认证
    ILLEGAL_REQUEST(4050, "非法提交，请重新处理"),
    AUTH_ERROR(4051, "认证失败，请稍后重试"),
    PARAMS_ERROR(4052, "参数错误"),
    CORS_ERROR(4053, "cors校验错误"),
    OTHER(5001, "其他错误"), //其他错误 ;

    PARSE_RESPONSE_ERROR(5002, "解析返回结果错误"),//解析返回结果错误
    BLAK_MESSAGE(6000, ""), //服务器返回错误信息
    SERVICE_ERROR(5003, "系统错误"); //服务器返回错误信息


    private final String message;
    private final int code;
    static final Map<Integer, ErrorType> codeMapping = Arrays.stream(ErrorType.values())
            .collect(Collectors.toMap(ErrorType::code, type -> type));

    ErrorType(int code) {
        this.code = code;
        message = this.name().toLowerCase();
    }

    ErrorType(int code, String message) {
        this.message = message;
        this.code = code;
    }

    public String message() {
        if (message == null) {
            return this.name();
        }
        return message;
    }

    public int code() {
        return code;
    }

    public <T> T throwThis(Function<ErrorType, ? extends RuntimeException> errorTypeFunction) {
        throw errorTypeFunction.apply(this);
    }

    public <T> T throwThis(BiFunction<ErrorType, String, ? extends RuntimeException> errorTypeFunction, String message) {
        throw errorTypeFunction.apply(this, message);
    }

    public static Optional<ErrorType> fromCode(int code) {
        return Optional.ofNullable(codeMapping.get(code));
    }
}
